<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 方法拦截
        let arr = []
        let method = ['push','pop','shift','unshift']
        let arr_method = Object.create(Array.prototype)
        method.forEach(method=>{
            arr_method[method] = function(){
                console.log('调用的拦截方法')
                // 拦截的时候设置响应式，
                Reactive(arguments)
                let res = Array.prototype[method].apply(this,arguments)
                return res
            }
        })
        arr.__proto__ = arr_method
        /* 
        arr.__proto__ -> Array.prototype   .__prototype ->Object.prototype
        中间加一层
        arr.__proto__ -> temp    .__proto__->Array.prototype   .__prototype ->Object.prototype
        */

        let obj = {
            name:'lihua',
            age:20,
            gender:'男',
            item:{
                one:1,
                two:2
            },
            goal:[
                {math:99},
                {english:100}
            ]

        }
        function defineReactive(obj,key,val){
            // console.log(obj,key,val),
            if(typeof(val) === 'object'){//这里包括数组和对象，数组也是特殊的对象
                Reactive(val)
                return
            }
            Object.defineProperty(obj,key,{
                get(){
                    console.log('访问属性'+key)
                    return val
                },
                set(nVal){
                    console.log('设置属性'+key+":"+nVal)
                    if(typeof(nVal) === 'object'){
                        Reactive(nVal)
                    }
                    val = nVal
                }
            })
        }
        // 这个只能实现单层的响应式
        /* for(let i in obj){
            defineReactive(obj,i,obj[i])
        } */
        function Reactive(obj){
            let keys = Object.keys(obj)
            // console.log(keys)
            for(let i = 0; i < keys.length; i++){
                let key = keys[i]
                let val = obj[key]
                if(Array.isArray(val)){//如果是数组,添加拦截方法
                    val.__proto__ = arr_method
                }
                // console.log(obj,key,val)
                // 如果是引用类型就需要进行递归
                // 如果不是引用类型需要调用defineReactive设置成响应式
                    // 字面量或者是对象类型的数据
                defineReactive(obj,key,val)
            }
        }
        Reactive(obj)


       
    </script>
</body>
</html>